package com.aizuda.boot.modules.business.department.service.impl;

import com.aizuda.boot.modules.business.department.domain.response.DepartmentDetailVO;
import com.aizuda.boot.modules.business.department.domain.response.DepartmentInfoDTO;
import com.aizuda.boot.modules.business.department.domain.response.DepartmentTreeVO;
import com.aizuda.boot.modules.business.department.domain.response.EmployeeVO;
import com.aizuda.boot.modules.business.permission.domain.entity.DepartmentEmployeeRelEntity;
import com.aizuda.boot.modules.business.permission.domain.entity.DepartmentEntity;
import com.aizuda.boot.modules.business.permission.domain.entity.EmployeeEntity;
import com.aizuda.boot.modules.business.employee.mapper.DepartmentEmployeeRelMapper;
import com.aizuda.boot.modules.business.department.mapper.DepartmentMapper;
import com.aizuda.boot.modules.business.employee.mapper.EmployeeMapper;
import com.aizuda.boot.modules.business.department.service.DepartmentService;
import com.aizuda.boot.modules.system.entity.SysDepartment;
import com.aizuda.boot.modules.system.mapper.SysDepartmentMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sangyirong
 * @version 1.0
 * @date 2025/5/15
 */
@Slf4j
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, DepartmentEntity> implements DepartmentService {
    @Resource
    DepartmentMapper departmentMapper;
    @Resource
    DepartmentEmployeeRelMapper departmentEmployeeRelMapper;
    @Resource
    EmployeeMapper employeeMapper;
    @Resource
    SysDepartmentMapper sysDepartmentMapper;

    @Override
    public List<DepartmentTreeVO> getDepartmentTree() {
        // 获取所有可用的部门
        List<DepartmentEntity> allDepartments = this.list(
            new LambdaQueryWrapper<DepartmentEntity>()
                .eq(DepartmentEntity::getEnable, 1)
                .eq(DepartmentEntity::getIsDeleted, false)
                .orderByAsc(DepartmentEntity::getSort)
        );
        
        log.info("查询到的部门数量: {}", allDepartments.size());
        if (allDepartments.isEmpty()) {
            log.warn("未查询到任何部门数据");
            return new ArrayList<>();
        } else {
            log.info("部门数据: {}", allDepartments);
        }
        
        // 找到所有根节点（parentNodeId为null的节点）
        List<DepartmentEntity> rootDepartments = allDepartments.stream()
            .filter(dept -> dept.getNodeParentId() == null)
            .collect(Collectors.toList());

        // 将其他部门按parentNodeId分组
        Map<Long, List<DepartmentEntity>> childrenMap = allDepartments.stream()
            .filter(dept -> dept.getNodeParentId() != null)
            .collect(Collectors.groupingBy(DepartmentEntity::getNodeParentId));

        // 跳过根节点，直接返回根节点的子节点作为顶级节点
        List<DepartmentTreeVO> result = new ArrayList<>();
        for (DepartmentEntity rootDept : rootDepartments) {
            List<DepartmentEntity> rootChildren = childrenMap.get(rootDept.getNodeId());
            if (rootChildren != null && !rootChildren.isEmpty()) {
                // 将根节点的子节点作为顶级节点
                result.addAll(rootChildren.stream()
                    .map(dept -> buildDepartmentTreeNode(dept, childrenMap))
                    .collect(Collectors.toList()));
            }
        }
        
        return result;
    }

    @Override
    public List<DepartmentTreeVO> getDepartmentTreeByParentId(Long parentNodeId) {
        // 获取所有可用的部门
        List<DepartmentEntity> allDepartments = this.list(
            new LambdaQueryWrapper<DepartmentEntity>()
                .eq(DepartmentEntity::getEnable, 1)
                .eq(DepartmentEntity::getIsDeleted, false)
                .orderByAsc(DepartmentEntity::getSort)
        );
        
        log.info("根据父节点[{}]查询到的部门数量: {}", parentNodeId, allDepartments.size());
        
        return buildDepartmentTree(allDepartments.stream()
            .filter(dept -> parentNodeId.equals(dept.getNodeParentId()))
            .collect(Collectors.toList()));
    }

    /**
     * 构建部门树形结构
     *
     * @param departments 部门列表
     * @return 树形结构的部门列表
     */
    private List<DepartmentTreeVO> buildDepartmentTree(List<DepartmentEntity> departments) {
        // 找到所有根节点（parentNodeId为null的节点）
        List<DepartmentEntity> rootDepartments = departments.stream()
            .filter(dept -> dept.getNodeParentId() == null)
            .collect(Collectors.toList());

        // 将其他部门按parentNodeId分组
        Map<Long, List<DepartmentEntity>> childrenMap = departments.stream()
            .filter(dept -> dept.getNodeParentId() != null)
            .collect(Collectors.groupingBy(DepartmentEntity::getNodeParentId));

        // 递归构建树形结构
        return rootDepartments.stream()
            .map(dept -> buildDepartmentTreeNode(dept, childrenMap))
            .collect(Collectors.toList());
    }

    /**
     * 递归构建部门树节点
     *
     * @param department 当前部门
     * @param childrenMap 子部门映射
     * @return 树节点
     */
    private DepartmentTreeVO buildDepartmentTreeNode(DepartmentEntity department, Map<Long, List<DepartmentEntity>> childrenMap) {
        DepartmentTreeVO treeNode = new DepartmentTreeVO();
        BeanUtils.copyProperties(department, treeNode);

        // 获取子部门并递归构建
        List<DepartmentEntity> children = childrenMap.getOrDefault(department.getNodeId(), new ArrayList<>());
        if (!children.isEmpty()) {
            treeNode.setChildren(
                children.stream()
                    .map(child -> buildDepartmentTreeNode(child, childrenMap))
                    .collect(Collectors.toList())
            );
        }

        return treeNode;
    }

    @Override
    public DepartmentDetailVO getDepartmentDetail(Long departmentId) {
        if (departmentId == null){
        return departmentMapper.getTotalDeparment();
        }
        // 1. 获取当前部门信息
        DepartmentEntity department = departmentMapper.selectById(departmentId);
        if (department == null || department.getIsDeleted()) {
            return null;
        }

        DepartmentDetailVO result = new DepartmentDetailVO();
        BeanUtils.copyProperties(department, result);

        // 2. 获取所有子部门
        List<DepartmentEntity> allDepartments = departmentMapper.selectList(
                new LambdaQueryWrapper<DepartmentEntity>()
                        .eq(DepartmentEntity::getIsDeleted, false)
                        .like(DepartmentEntity::getPaths, department.getNodeId().toString())
        );

        // 构建子部门树
        Map<Long, List<DepartmentEntity>> parentChildMap = allDepartments.stream()
                .filter(dept -> !dept.getId().equals(departmentId))
                .collect(Collectors.groupingBy(DepartmentEntity::getNodeParentId));

        result.setChildren(buildDepartmentTree(department.getNodeId(), parentChildMap));

        // 3. 获取当前部门及子部门的所有员工
        Set<Long> allDepartmentIds = allDepartments.stream()
                .map(DepartmentEntity::getId)
                .collect(Collectors.toSet());
        allDepartmentIds.add(departmentId);

        // 获取部门-员工关系
        List<DepartmentEmployeeRelEntity> employeeRels = departmentEmployeeRelMapper.selectList(
                new LambdaQueryWrapper<DepartmentEmployeeRelEntity>()
                        .in(DepartmentEmployeeRelEntity::getDepartmentId, department.getId())
                        .eq(DepartmentEmployeeRelEntity::getIsDeleted, false)
        );

        // 获取员工信息
        Set<Long> employeeIds = employeeRels.stream()
                .map(DepartmentEmployeeRelEntity::getEmployeeId)
                .collect(Collectors.toSet());

        if (!employeeIds.isEmpty()) {
            List<EmployeeEntity> employees = employeeMapper.selectList(
                    new LambdaQueryWrapper<EmployeeEntity>()
                            .in(EmployeeEntity::getId, employeeIds)
                            .eq(EmployeeEntity::getIsDeleted, false)
            );

            // 构建员工VO，包含其所有部门信息
            List<EmployeeVO> employeeVOs = employees.stream().map(employee -> {
                EmployeeVO employeeVO = new EmployeeVO();
                BeanUtils.copyProperties(employee, employeeVO);

                // 获取员工的所有部门信息
                List<EmployeeVO.DepartmentVO> departmentVOs = employeeRels.stream()
                        .filter(rel -> rel.getEmployeeId().equals(employee.getId()))
                        .map(rel -> {
                            EmployeeVO.DepartmentVO deptVO = new EmployeeVO.DepartmentVO();
                            DepartmentEntity dept = allDepartments.stream()
                                    .filter(d -> d.getId().equals(rel.getDepartmentId()))
                                    .findFirst()
                                    .orElse(null);
                            if (dept != null) {
                                deptVO.setId(dept.getId());
                                deptVO.setName(dept.getName());
                                deptVO.setCode(dept.getCode());
                                deptVO.setIsMainDepartment(rel.getDepartmentBelong() == 1);
                                deptVO.setIsLeader(rel.getLeader());
                            }
                            return deptVO;
                        })
                        .collect(Collectors.toList());
                employeeVO.setDepartments(departmentVOs);
                return employeeVO;
            }).collect(Collectors.toList());

            result.setEmployees(employeeVOs);
        }

        return result;
    }

    private List<DepartmentDetailVO> buildDepartmentTree(Long parentNodeId, Map<Long, List<DepartmentEntity>> parentChildMap) {
        List<DepartmentEntity> children = parentChildMap.get(parentNodeId);
        if (children == null || children.isEmpty()) {
            return Collections.emptyList();
        }

        return children.stream()
                .map(child -> {
                    DepartmentDetailVO childVO = new DepartmentDetailVO();
                    BeanUtils.copyProperties(child, childVO);
                    childVO.setChildren(buildDepartmentTree(child.getNodeId(), parentChildMap));
                    return childVO;
                })
                .sorted(Comparator.comparing(DepartmentDetailVO::getSort, Comparator.nullsLast(Comparator.naturalOrder())))
                .collect(Collectors.toList());
    }

    /**
     * 获取员工主部门信息
     *
     * @param employeeId 员工ID
     * @return 主部门信息
     */
    @Override
    public DepartmentInfoDTO getEmployeeMainDepartment(Long employeeId) {
        // 使用新的sys_user_department表查询
        SysDepartment sysDepartment = sysDepartmentMapper.selectMainDepartmentByUserId(employeeId);
        if (sysDepartment == null) {
            return null;
        }
        
        // 转换为DepartmentInfoDTO
        DepartmentInfoDTO departmentInfoDTO = new DepartmentInfoDTO();
        departmentInfoDTO.setId(sysDepartment.getId());
        departmentInfoDTO.setNodeId(sysDepartment.getId()); // 使用id作为nodeId
        departmentInfoDTO.setNodeParentId(sysDepartment.getPid()); // 使用pid作为父节点ID
        departmentInfoDTO.setName(sysDepartment.getName());
        departmentInfoDTO.setCode(sysDepartment.getCode());
        departmentInfoDTO.setRemark(sysDepartment.getRemark());
        departmentInfoDTO.setSort(sysDepartment.getSort());
        
        return departmentInfoDTO;
    }

    @Override
    public DepartmentTreeVO getDepartmentTreeByTenant(Integer tenantId) {
        // 获取所有可用的部门
        List<DepartmentEntity> allDepartments = this.list(
                new LambdaQueryWrapper<DepartmentEntity>()
                        .eq(DepartmentEntity::getEnable, 1)
                        .eq(DepartmentEntity::getIsDeleted, false)
                        .orderByAsc(DepartmentEntity::getSort)
        );

        log.info("查询到的部门数量: {}", allDepartments.size());
        if (allDepartments.isEmpty()) {
            log.warn("未查询到任何部门数据");
            return new DepartmentTreeVO();
        } else {
            log.info("部门数据: {}", allDepartments);
        }

        return buildDepartmentTree(allDepartments).get(0);
    }

    @Override
    public Map<Long, String> getAllDepartmentNames() {
        Map<Long, String> departmentNameMap = list().stream()
                .collect(Collectors.toMap(DepartmentEntity::getId, DepartmentEntity::getName));
        return departmentNameMap;
    }
}